package com.py.payment.nettys.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

@Slf4j
@Component
public class NettyServer {

    public void start(InetSocketAddress address) {
        // 服务器NIO线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {

            ServerBootstrap bootstrap = new ServerBootstrap()
                    .group(bossGroup, workerGroup)
                    // 指定通道
                    .channel(NioServerSocketChannel.class)
                    // 指定端口 设置套接字地址
                    .localAddress(address)
                    // 自定义处理类
                    .childHandler(new NettyServerChannelInitializer())
                    // 可连接队列数,对应TCP/IP协议listen函数中backlog参数
                    .option(ChannelOption.SO_BACKLOG,128)
                    //设置通道Channel的分配器
                    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    // 保持长连接, 2小时无数据激活心跳机制
//                    .childOption(ChannelOption.SO_KEEPALIVE,true)
                    ;
            // 绑定端口, 开始接收进来的连接
            ChannelFuture future = bootstrap.bind(address).sync();
            if(future.isSuccess()){
                log.info("netty服务器开始监听端口: {}",address.getPort());
            }
            // 关闭channel和块, 直到被关闭
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
